const util = require('../util');

class ControllerTemplate {
  constructor(tableName, fields) {
    this.tableName = util.underlineToHump(tableName);
    this.fields = fields;
    this.className = util.upFirst(this.tableName);
  }

  generateFile() {
    this.text = '';
    this.header();
    this.start();
    this.create();
    this.findAll();
    this.findOne();
    this.update();
    this.end();
    return this.text;
  }

  header() {
    this.text += `const moment = require('moment');

      const config = require('../configs');
      const db = require('../util/db');
      const util = require('../util');
      const myResponse = require('../util/response');
        
      const ${this.className} = db.${this.tableName};
      const sequelize = db.sequelize;\n\n`;
  }

  start() {
    this.text += `class ${this.className}Controller {\n\n`;
  }

  create() {
    var filedParams = '';
    for (let i = 0; i < this.fields.length; i++) {
      filedParams += `${this.fields[i]}:${this.fields[i]},`;
    }
    this.text += `static async create${this.className}(ctx) {
        var {${this.fields.join(',')}} = ctx.request.body;
  
        try {
          await util.schema.validateAsync({
          });
        } catch (error) {
          myResponse.error(ctx, myResponse.code.paramError, error.message);
          return;
        }

        try {
          var ${this.tableName} = await ${this.className}.create({
            ${filedParams}
            createTime: moment()
          });
          myResponse.success(ctx, ${this.tableName});
        } catch (error) {
          console.log(error);
          myResponse.error(ctx, myResponse.code.dbError);
          return;
        }
      }\n\n`;
  }

  findAll() {
    this.text += ` static async get${this.className}s(ctx) {
      var { limit, offset, type } = ctx.query;
      if (!(type && limit && offset)) {
        myResponse.error(ctx, myResponse.code.paramNotFound);
        return;
      }
      try {
        await util.schema.validateAsync({
          limit: limit,
          offset: offset
        });
      } catch (error) {
        myResponse.error(ctx, myResponse.code.paramError, error.message);
        return;
      }

      var options = {};
      try {
        var ${this.tableName}s = await ${this.className}.findAndCountAll({
          offset: parseInt(offset),
          limit: parseInt(limit),
          order: [['createTime', 'DESC']],
          where: options,
          raw: true
        });
        myResponse.success(ctx, ${this.tableName}s);
      } catch (error) {
        console.log(error);
        myResponse.error(ctx, myResponse.code.dbError);
        return;
      }
    }
    \n\n`;
  }

  findOne() {
    this.text += `static async get${this.className}(ctx) {
      var { id } = ctx.query;
      if (!id) {
        myResponse.error(ctx, myResponse.code.paramNotFound);
        return;
      }

      try {
        var ${this.tableName} = await ${this.className}.findOne({
          where: { id: id }
        });
        myResponse.success(ctx, ${this.tableName});
      } catch (error) {
        console.log(error);
        myResponse.error(ctx, myResponse.code.dbError);
        return;
      }}\n\n`;
  }

  update() {
    this.text += `static async update${this.className}(ctx) {
      var { id } = ctx.request.body;

      try {
        await util.schema.validateAsync({
        });
      } catch (error) {
        myResponse.error(ctx, myResponse.code.paramError, error.message);
        return;
      }

      try {
        var options = {
          updateTime: moment()
        };
        await ${this.className}.update(options, { where: { id: id } });
        myResponse.success(ctx);
      } catch (error) {
        console.log(error);
        myResponse.error(ctx, myResponse.code.dbError);
        return;
      }}\n\n`;
  }
  end() {
    this.text += `}\n\nexports = module.exports = ${this.className};`;
  }
}

exports = module.exports = ControllerTemplate;
